home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AMIGA-CD 2
/
Amiga-CD - Volume 2.iso
/
ungepackte_daten
/
1995
/
6
/
02
/
c++-kurs
/
dirtree.c
next >
Wrap
C/C++ Source or Header
|
1995-06-01
|
6KB
|
205 lines
/*
* DirTree.c © 1995 Clemens Marschner
* Implements Recursive Dir Tree class
*/
#include "DirTree.h"
#include <utility/tagitem.h>
struct BlockList *DirTree::SearchRek(char *sdir, char *pattern,
struct ExAllData *upperD, int rekurs) {
BPTR lock;
char *sbuffer = new char[512]; // nimmt Verzeichnisnamen auf
struct ExAllData *actual=0;
strncpy (sbuffer,sdir,512);
struct BlockList *blist=0, *rootlist=0;
if(rekurs == 0) running = TRUE;
rekurs++;
if(lock = Lock(sdir, SHARED_LOCK))
{
if(blist = ReadDir(lock))
{
if(upperD)
{
upperD->ed_downerB = (ULONG)blist;
} else
{
rootlist = blist;
}
blist->upper = upperD; // wenn kein upperd, dann autom. init mit 0l
int dirinIt=0;
if(rekurs == 1)
DirChanged(sdir);
for(actual = blist->ExAllData; actual; actual = actual->ed_Next)
{
if(actual->ed_Type < 0) {
long match;
match = MatchPatternNoCase(pattern,actual->ed_Name);
if(match)
{
FileFound(actual);
} else
{
long ioerr;
if(ioerr = IoErr())
PrintFault(ioerr,NULL);
}
}
}
for(actual = blist->ExAllData; actual; actual = actual->ed_Next)
{
if (actual->ed_Type > 0)
{
dirinIt=1;
if(actual->ed_Name)
{
if(!(AddPart(sbuffer,actual->ed_Name,512)))
{
Error("DirTree: Fehler bei der Verzeichnisbehandlung durch Addpart\n");
}
DirChanged(sbuffer);
SearchRek(sbuffer,pattern,actual,rekurs);
}
STRPTR pp = PathPart(sbuffer);
*pp = '\0';
}
}
if(!dirinIt && rekurs>1)
{
DeleteDirBlock(blist);
if(upperD)
{
upperD->ed_downerB = NULL;
}
}
if(!running)
{
// Abbruch funktioniert nocht nicht richtig...
// liegt aber, blaub' ich, am Compiler
// for(...; actual, running; ...) liefert immer TRUE zurück
// und bildet deshalb Endlosschleife
Error("Suchaktion abgebrochen.");
}
} else Error("DirTree: blist meldet Fehler\n");
UnLock(lock);
} else {
Fault(IoErr(), 0, sbuffer, FAULT_MAX);
Error(sbuffer);
}
rekurs--;
if(rekurs == 0)
return rootlist;
delete sbuffer;
}
void DirTree::DeleteDirBlock(struct BlockList *firstB) {
struct BlockList *actualB, *actualBCopy;
if(firstB) {
for(actualB=firstB; actualB;)
{
if(actualB->ExAllDCopy)
{
FreeVec(actualB->ExAllDCopy);
actualBCopy=actualB->next;
delete actualB;
actualB = actualBCopy;
} else actualB=NULL;
}
}
}
void DirTree::DeleteAllBlocks(struct BlockList *firstB,
struct ExAllData *upperD,int rekurs)
{
struct ExAllData *actual;
rekurs++;
if(firstB)
{
for(actual = firstB->ExAllData; actual; actual = actual->ed_Next)
{
if(actual)
{
if(actual->ed_Type > 0)
{
DeleteAllBlocks((struct BlockList*)actual->ed_downerB, actual,rekurs);
//ndirs++;
} else //nfiles++;
}
}
DeleteDirBlock(firstB);
}
rekurs--;
}
struct BlockList *DirTree::ReadDir(BPTR lock)
{
BOOL goon=TRUE;
BOOL err=FALSE;
struct ExAllControl *eac;
struct BlockList *firstB,*actualB;
eac = (struct ExAllControl*)AllocDosObject(DOS_EXALLCONTROL,TAG_DONE);
struct ExAllData *actualD;
int memcnt = 1;
ULONG bufsize = 48;
// könnte auch #defined werden, aber um variabel zu bleiben...
if(!eac)
{
Error("Recursive-Read: Error: Couldn't allocate DOS Object\n");
err = TRUE;
}
actualB = firstB = new struct BlockList;
actualB->BufSize = bufsize * sizeof(struct ExAllData);
actualB->ExAllDCopy =
actualB->ExAllData = (struct ExAllData*)
AllocVec(actualB->BufSize,MEMF_ANY|MEMF_CLEAR);
while (goon && (!err))
{
if(actualB->ExAllDCopy == 0l)
{
actualB->ExAllDCopy = actualB->ExAllData = NULL;
err = TRUE; goon = FALSE;
Error("Recursive-Read: Error: Not enough memory\n");
}
if(!err)
{
(goon = ExAll(lock, actualB->ExAllData,
actualB->BufSize,
ED_DATE,eac));
actualD = actualB->ExAllData;
if(goon)
{
actualB->next = new struct BlockList;
memcnt++;
actualB->next->BufSize = bufsize * (sizeof(struct ExAllData)-4);
actualB->next->ExAllDCopy =
actualB->next->ExAllData = (struct ExAllData*)
AllocVec(actualB->BufSize,MEMF_ANY|MEMF_CLEAR);
for(actualD = actualB->ExAllData; actualD->ed_Next;
actualD=actualD->ed_Next);
actualD->ed_Next = actualB->next->ExAllData;
// ist egtl. noch nicht def.
actualB = actualB->next;
actualB->next = NULL;
}
}
}
if(firstB->ExAllData->ed_Name == NULL && firstB->ExAllData)
{
FreeVec(firstB->ExAllData);
firstB->ExAllData = firstB->ExAllDCopy = NULL;
}
if(eac) FreeDosObject(DOS_EXALLCONTROL, eac);
if(err)
{
DeleteDirBlock(firstB);
return 0l;
}
return firstB;
}